import java.util.regex.*;
import java.util.*;
/**
 *  This class is the main class of the "World of Zuul" application. 
 *  "World of Zuul" is a very simple, text based adventure game.  Users 
 *  can walk around some scenery. That's all. It should really be extended 
 *  to make it more interesting!
 * 
 *  To play this game, create an instance of this class and call the "play"
 *  method.
 * 
 *  This main class creates and initialises all the others: it creates all
 *  rooms, creates the parser and starts the game.  It also evaluates and
 *  executes the commands that the parser returns.
 * 
 * @author  Michael Kölling and David J. Barnes
 * @version 2016.02.29
 */

public class Game 
{
    private HashMap<String, Thing> bags = new HashMap<>();
    private Parser parser;
    private Player player; 
    private Room currentRoom;
    private Monster monster;
    private Combat combat;
    private Thing thing;
    private Bag bag;
    
    /**
     * Create the game and initialise its internal map.
     */
    public Game() 
    {
        createRooms();
        parser = new Parser();
        player = new Player();
        combat = new Combat();
        bag = new Bag();
    }

    /**
     * Create all the rooms and link their exits together.
     */
    private void createRooms()
    {
        Room outside, danfang, sl, bedroom, lei, huo, klf, sy, mushi;
      
        // create the rooms
        outside = new Room("洞府大厅");
        danfang = new Room("你现在在丹房");
        sl = new Room("你在试炼之地");
        bedroom = new Room("你在卧室");
        lei = new Room("你在雷罚之地");
        huo = new Room("你正在炙炎之域");
        mushi = new Room("你在金仙墓室");
        klf = new Room("你在幻境阁");
        sy = new Room("你在玄灵秘境");
        
        //添加出口
        outside.setExit("east", klf);
        outside.setExit("north", danfang);
        outside.setExit("west", sl);
        danfang.setExit("north", sl);
        danfang.setExit("east", bedroom);
        danfang.setExit("south", outside);
        
        bedroom.setExit("north", lei);
        bedroom.setExit("west", danfang);
        
        sl.setExit("north", lei);
        sl.setExit("east", huo);
        sl.setExit("south", danfang);
        sl.setExit("west", outside);
        
        lei.setExit("north", mushi);
        lei.setExit("east", bedroom);
        lei.setExit("south", sl);
        
        klf.setExit("north", huo);
        klf.setExit("west", sy);
        klf.setExit("south", outside);
        
        huo.setExit("north", mushi);
        huo.setExit("west", sl);
        huo.setExit("south", klf);
        
        sy.setExit("east", klf);
        
        mushi.setExit("south", lei);
        mushi.setExit("east", huo);
        
        //添加丹药
        danfang.putThing(new Thing("五品活血丹", 100));
        danfang.putThing(new Thing("四品活血丹", 80));
        danfang.putThing(new Thing("五品玄元丹", 60));
        danfang.putThing(new Thing("四品玄元丹", 40));
        danfang.putThing(new Thing("三品赤阳丹", 20));
        
        sl.putThing(new Thing("三品活血丹", 50));
        sl.putThing(new Thing("三品子午丹", 15));
        
        lei.putThing(new Thing("三品子午丹", 15));
        
        huo.putThing(new Thing("三品玄元丹", 20));
        
        sy.putThing(new Thing("五品活血丹", 100));
        sy.putThing(new Thing("五品活血丹", 100));
        
        mushi.putThing(new Thing("八品解毒丹", 10000));
        
        //添加功法
        bedroom.putThing(new Thing("精权月影剑", 30));
        sy.putThing(new Thing("黑莲灭空剑",50));
        
        //添加怪物
        sl.putMonster(new Monster("开明兽", 100, 210, 180));
        huo.putMonster(new Monster("炼狱当康", 100, 220, 190));
        klf.putMonster(new Monster("苍魂鸣蛇", 140, 225, 200));
        klf.putMonster(new Monster("混沌之灵", 120, 210, 188));
        lei.putMonster(new Monster("九霄雷神", 120, 210, 188));
        mushi.putMonster(new Monster("墓室主人", 210, 245, 220));
        
        currentRoom = outside;  // start game outside
    }

    /**
     *  Main play routine.  Loops until end of play.
     */
    public void play() 
    {            
        printWelcome();

        // Enter the main command loop.  Here we repeatedly read commands and
        // execute them until the game is over.
                
        boolean finished = false;
        while (! finished) {
            Command command = parser.getCommand();
            finished = processCommand(command);
        }
        System.out.println("你使用你仅剩的传送卷轴离开了洞府，未能取得丹药，拯救道侣失败！");
    }
    
    /**
     * Print out the opening message for the player.
     */
    private void printWelcome()
    {
        System.out.println();
        System.out.println("你是一位金丹强者，但道侣被仇人暗算身中剧毒已奄奄一息，需要一枚八品解毒丹才能救活道侣");
        System.out.println("经过打听，你知道了有一位元婴强者的洞府里面有一枚八品解毒丹，然后你就踏上了你的旅程");
        System.out.println("输入 help 可以查看攻略");
        System.out.println();
        System.out.println("你在" + currentRoom.getDescription());
        currentRoom.checkThing();
       // System.out.print("Exits: ");
        currentRoom.printExits();
    }

    /**
     * Given a command, process (that is: execute) the command.
     * @param command The command to be processed.
     * @return true If the command ends the game, false otherwise.
     */
    private boolean processCommand(Command command) 
    {
        boolean wantToQuit = false;

        if(command.isUnknown()) {
            System.out.println("我不知道你输入的是什么...");
            return false;
        }

        String commandWord = command.getCommandWord();
        CommandWord cmd = CommandWord.valueOf(commandWord.toUpperCase());
        
        switch(cmd) {
            case HELP:
                printHelp();
                break;
            case GO:
                player.walk();
                // if (!player.isAlive())
                // {
                    // System.out.println("您已经没有体力了，游戏结束！");
                    // return true;
                // }
                goRoom(command);
                break;
            case QUIT:
                wantToQuit = quit(command);
                break;
            case EAT:
                eat(command);
                break;
            case PICK:
                pick(command);
                break;
            case BAG:
                bag.checkBag();
                break;
            case FIGHT:
                fight(command);
                break;
            case USE:
                use(command);
                break;
            default:
        }
         return wantToQuit;
    }
    
    private void pick(Command command)
    {
        String name = command.getSecondWord();
        if(!command.hasSecondWord()) {
            if (currentRoom.getThing(name) == null) {
                System.out.println("请选择要拿的东西");
                return;
            }
        }
        else if(currentRoom.getThing(name) == null) {
            System.out.println("这个房间里面没有这个东西");
            return;
        }
        //if(!bags.isEmpty()){
        Thing thing = currentRoom.getThing(name);
        bag.pick(thing);
        if(currentRoom.checkDanyao().equals(name)) {
            System.out.println("你成功拿走了解毒丹，并且使用传送卷轴离开了洞府，游戏通关！");
            currentRoom.removeThing(name);
            System.exit(0);
        }
        currentRoom.removeThing(name);
        
    }
    
    private void eat(Command command) 
    {
        if(!command.hasSecondWord()) {
            System.out.println("请选择要吃的东西？");
            return;
        }
        String name = command.getSecondWord();
        
        if (bag.getThing(name) != null) {
            Thing thing = bag.getThing(name);
            System.out.println("你吃下了一颗：" + thing.toString());
            player.eat(thing);
            player.check();
            bag.removeThing(name);
        }
        else if(currentRoom.getThing(name) != null){
            Thing thing = currentRoom.getThing(name);
            System.out.println("你吃下了一颗：" + thing.toString());
            player.eat(thing);
            player.check();
            currentRoom.removeThing(name);
        }
        else {
            System.out.println("这个房间和背包里面都没有这个东西");
        }
    }
    
    private void use(Command command) 
    {
        String name = command.getSecondWord();
        if (currentRoom.getThing(name) == null && bag.getThing(name) == null) {
            System.out.println("这个房间和背包里面都没有可修炼的功法");
        }
        else if(currentRoom.getThing(name) != null){
            Thing thing = currentRoom.getThing(name);
            System.out.println("你修炼了" + thing.toString());
            player.useWeapon(thing);
            player.check();
            currentRoom.removeThing(name);
        }
        else {
            Thing thing = bag.getThing(name);
            System.out.println("你修炼了" + thing.toString());
            player.useWeapon(thing);
            player.check();
            bag.removeThing(name);
        }
    }
    
    private void fight(Command command)
    {
        String name = command.getSecondWord();
        if(!command.hasSecondWord()) {
            System.out.println("请选择要攻击的怪物？");
            return;
        }
        if (currentRoom.getMonster(name) == null) {
            System.out.println("这个房间里面没有这个怪物");
        }
        else {
            Monster monster = currentRoom.getMonster(name);
            //System.out.println("吃掉了：" + food.toString());
            //player.eat(food);
            combat.combats(player, monster);
            if (!player.isAlive() || !player.isAblue())
            {
                death(); 
            }
            player.check();
            currentRoom.removeMonster(name);
            currentRoom.checkMonster();
            if(currentRoom.checkRoomMonster()) {
                if(currentRoom.checkHost().equals(name)){
                    System.out.println("你已经打败了墓室主人，快拿走丹药去救你的道侣吧！");
                    currentRoom.checkThing();
                    currentRoom.printExits();
                }
                else{
                    currentRoom.checkThing();
                    currentRoom.printExits();
                }
            }
        }
    }
    
    private void death()
    {
        if(player.getLife() <= 0) {
            player.check();
            System.out.println("你的生命力耗尽了,游戏失败！");
            System.exit(0);
        }
        else if(player.getBlue() < 0) {
            player.check();
            System.out.println("你的真气耗尽了，无法再与怪物战斗，无力再去取丹药，传送卷轴也没有真气发动，已无路可退，游戏失败！");
            System.exit(0);
        }
        
    }
    
    // implementations of user commands:

    /**
     * Print out some help information.
     * Here we print some stupid, cryptic message and a list of the 
     * command words.
     */
    private void printHelp() 
    {
        System.out.println("丹药分为四种：活血丹、玄元丹、蓄力丹");
        System.out.println("活血丹：按照品级的不同回复不同的血量");
        System.out.println("玄元丹：按照品级的不同回复不同的真气");
        System.out.println("赤血丹：按照品级的不同增加不同的攻击力");
        System.out.println("子午丹：按照品级的不同增加不同的防御力");
        System.out.println("修炼功法可以增加攻击力，每种增加功法攻击力都不一样");
        System.out.println("每到一个房间，只有把里面的怪物杀完才能离开房间和拿里面的东西，除非你用传送卷轴离开洞府");
        System.out.println("quit：使用传送卷轴逃离洞府");
        System.out.println("go：前往下一个房间");
        System.out.println("eat：吃丹药");
        System.out.println("pick：把指定东西放入衲戒");
        System.out.println("bag：打开衲戒");
        System.out.println("fight：攻击指定怪物");
        System.out.println("use：修炼功法");
        System.out.println();
        CommandWords.printCommmands();
    }

    /** 
     * Try to go in one direction. If there is an exit, enter
     * the new room, otherwise print an error message.
     */
    private void goRoom(Command command) 
    {
        if(!command.hasSecondWord()) {
            // if there is no second word, we don't know where to go...
            System.out.println("去哪里");
            return;
        }

        String direction = command.getSecondWord();
        Room nextRoom = currentRoom.goNext(direction);
        
        
        if (nextRoom == null) {
            System.out.println("这个房间没有这个入口！");
        }
        else {
            currentRoom = nextRoom;
            System.out.println("你在" + currentRoom.getDescription());
            currentRoom.checkMonster();
            if (currentRoom.checkRoomMonster()) {
                currentRoom.checkThing();
                currentRoom.printExits();
            }
        }
    }
    
    /** 
     * "Quit" was entered. Check the rest of the command to see
     * whether we really quit the game.
     * @return true, if this command quits the game, false otherwise.
     */
    private boolean quit(Command command) 
    {
        if(command.hasSecondWord()) {
            System.out.println("输入quit使用传送卷轴逃离洞府");
            return false;
        }
        else if(player.getBlue() < 20) {
            System.out.println("真气不足，发动卷轴需要20真气，需先回复真气后再次发动");
            return false;
        }
        else {
            return true;  // signal that we want to quit
        }
    }
}
